package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;

/**
 * @author ：石破天
 * @date ：Created in 2022年11月16日
 * @description ：
 * @version: 1.0
 */
@Slf4j
@RestController
@RequestMapping("/employee")
@Api(tags="员工模块")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    //处理器 但是 要不要统一返回格式呢!!!
    /**
     *   登录处理步骤
     *     1:在参数位置接收 员工用户名和密码  Employee对象接收
     *     2: 对密码加密
     *     3: 根据用户名查询数据库 该用户的信息 返回一个员工
     *        通过 service查  ...service应该有 根据用户名条件查询用户信息
     *        T getOne(Wrapper<T> queryWrapper);
     *     4:判断用户 是null 登录失败 返回失败...
     *     5:不是null 有这个员工 ,再进行密码比对
     *     6:  false 说明密码错误 返回失败
     *     7: true 继续 获取用户中的状态 进行判断
     *     8 根据状态 是1  成功  0 失败
     *     9  是1 把用户id存到session中
     *        返回成功 返回该员工对象
     */
    @ApiOperation("登录接口")
    @PostMapping("/login")
    public R<Employee> login(@RequestBody Employee employee, HttpSession session){
        log.info("员工开始登录了....");
        //1: 对密码加密  md5加密形式 固定语法
        String password = employee.getPassword();//原始密码
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        //  把你字符串变成了字节 对原生字节进行了一个不可逆的加密方式...
        // 原始密码变成了加密后的密码
        String username = employee.getUsername();//用户户录入的密码

        //2: 根据用户名查询数据库 该用户的信息 返回一个员工

        // select * from employee where username =  ''  值来源于 employee.getUsername

        //  这个方法 是从官网查的  根据条件查询 查询一条
        //  T getOne(Wrapper<T> queryWrapper);
        //  Wrapper 是来 封装条件的对象
        //   QueryWrapper 一般封装 where后面条件
        //    username =  ''
//        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
//        // queryWrapper 的目的是拼接出来 username = employee.getUsername();
//        queryWrapper.eq("username",username);// username = username变量的值
//                // eq 就是 等于号  等于号两边 一个是字段 一个是值
        // 上述操作存在硬编码  就是有字符串由程序员直接书写 容易出问题...
        //  下面可消除硬编码
        //  QueryWrapper的儿子  LambdaQueryWrapper
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        //  queryWrapper.eq("username",username);  上下两个功能一模一样
        //           "username"手动录入 变成了选择
        //           类名::get要的字段名
        //  Employee::getUsername 代表了 "username"字符串
        wrapper.eq(Employee::getUsername,username);
        Employee emp = employeeService.getOne(wrapper);

        // 3 如果对象 是null说明 登录失败
        if(emp==null){
            return R.error("用户名或密码不存在");
        }
        // 4: 如果没return结束方法 执行到这里了 说明 emp有该对象
         // 再进行密码判断
        if(!emp.getPassword().equals(password)){//密码不一致
            return R.error("用户名或密码不存在");
        }
        //5: 如果执行到 69行 说明 用户存在 密码正确!!!!
        // 判断状态
        if(emp.getStatus() == 0){// 被锁定了  封号了...
            return R.error("账号已禁用,请联系管理员....高进...按小时收费");
        }
       // 6: 74行 用户有 密码对 没有锁定账号
        //先把登录成功对象 的 id 存到session中
//        //参数位置  HttpServletRequest request)
//        // 用这种方式
//        request.getSession().setAttribute("employee",emp.getId());
         session.setAttribute("employee",emp.getId());
        // 把id 存到 session中
   log.info("员工登录成功");
        return R.success(emp);
    }

    @PostMapping("/logout")
    public R<String> logout(HttpSession session) {
        //退出登录
        log.info("员工正在退出登录...");
        // 清除掉 session 存储的id
        session.removeAttribute("employee");
        // 销毁session  节约内存空间....
        session.invalidate();
        return R.success("退出成功");
    }

    /**
     * 添加员工方法
     * @param employee 添加员的基本信息
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody Employee employee,HttpSession session){
        //1: 通过日志 打印接收到数据
        log.info("员工基本信息"+employee);
        log.info("[员工基本信息:{}]",employee);
        log.info("当前 经过 save方法 线程id:"+Thread.currentThread().getId());
        //2: 设置密码属性
        String password = DigestUtils.md5DigestAsHex("123456".getBytes());
        // 把 123456 字符串转换字节 进行md5加密
        employee.setPassword(password);
        // 现在这个employee是不是 就搞定了 除了 id 和 status
        // 执行添加操作 boolean save(T entity);
        employeeService.save(employee);

        //最后响应成功
        return R.success("添加成功");

    }

    /**
     * 分页查询员工信息
     * @param page   当前页码
     * @param pageSize  每页显示条数
     * @param name  查询的条件 where后面的
     * @return  返回给前端的 分页数据
     */
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){//问号后面参数  直接接收
//        1: 构建一个Page对象 分页构造器
            Page<Employee> pageInfo = new Page<>(page,pageSize);
//        2: 有条件 构建一个条件构造器 wrapper
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
//        加条件...(显性条件 和 隐形条件)
        // select *from employee where name like ''  limit n,m;
        // where name like ''
        // name 如果没传递过来就不加 like语句
        if(name!=null&&name.length()>0){
            wrapper.like(Employee::getName,name);//  'name' like 接收的name
        }
        // 隐形条件  潜规则.... 一般来说数据有一个 默认的排序规则
        //  根据时间倒序
        wrapper.orderByDesc(Employee::getUpdateTime); //根据更新时间倒序
//        3: 执行分页查询
//                service里面分页查询方法
        employeeService.page(pageInfo,wrapper);
//        4: 把 分页对象设置到 返回的数据即可...
        //pageInfo 执行完就是具备 每页显示内容
        return R.success(pageInfo);//返回分页对象
    }


    /**
     *  更新方法   具备开发经验的代码
     *     可以根据id更新任何可更新的内容!!!!!
     *       根据id可以更新状态
     *          还可以更新其他信息
     * @param employee
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody Employee employee,HttpSession session){
        log.info("[需要更新内容:{}]",employee);
        log.info("当前 经过 update方法 线程id:"+Thread.currentThread().getId());
//        // 根据 ID 选择修改
//        // boolean updateById(T entity);
        employeeService.updateById(employee);

        return R.success("更新信息成功");
    }

    /*
       根据id进行查询
     */
    @GetMapping("/{id}")
    public R<Employee> getById(@PathVariable Long id){
        //找到servcie
        Employee employee = employeeService.getById(id);

        if(employee==null){//给的id后台没了
            return R.error("兄嘚 该id对应的用户已经不在数据库了");
        }

        return R.success(employee);
    }
}
